MLPA
An MLPA (MLP Archive) file is an archive file that contains all of the game's content files. It is also commonly known as an .obb (Opaque Binary Blob) file, because that is the extension commonly associated with the file type. However the .obb extension is used for many Android games, each with unique content and formats, and is not unique to My Little Pony. MLPA files can be extracted with the MLPArch tool. Format An MLPA file is essentially just a bunch of files tacked together with a minimal header and file index. It is usually named "main.1050.com.gameloft.android.ANMP.GloftPOHM.obb" on Android systems, and located in the game's data folder. The MLPA has an unusual format, because all offsets in the file are stored as plain-text decimal numerals, instead of encoded values. An MLPA has 3 main segments: *The header, a short segment describing the location of the index *The data segment, which contains all of the data in the archive *The index, a listing of all the files in the archive, along with their offsets Header An MLPA file has a very simplistic header, consisting only of a string containing a number representing the starting offset of the index. It is unknown whether this is a variable or fixed length header, however all versions of the main MLPA distributed with the game have a 9 byte header. It is unknown whether the game will accept a header with a length other than 9-bytes. Data The data segment consists solely of the data of all the files in the archive, concatenated one after another. The data segment is unencrypted and uncompressed. Index The index segment consists of a number of file entries which specify the names and data offsets of the files in the archive. Each index entry consists of 4 numerical fields and a string, and is separated from the next entry by a Unix newline (LF, 0x0A). As noted, each numerical field is stored as a series of plain-text digits, instead of an encoded value. Each field is separated from the next by a space character (0x20). Because there is no data stored in the entry about how long each field is, or even how long the entry itself is, each entry must be separated from the next by reading the index as if it was a text file. (That is, reading until you reach a newline.) Each field must be separated from the next by using the space characters as delimiters. It is also important to note that the last field may contain spaces, so the entry must be parsed by identifying the first 4 fields, then treating the rest of the "line" as the last field. Because there is no record of how many entries are in the index, it is necessary to continue parsing index entries until the end of the file is reached. There are 5 fields in each index entry: *(Numeral) Start offset, the location, relative to the beginning of the archive, where this file begins. *(Numeral) End offset, the location where this file ends. *(Numeral) Magic 1, an unknown field. *(Numeral) Magic 2, another unknown field. It is important to note that in official MLPAs, this field is always equal to the Start offset. *(String) Path, the full path to the location of the file. Magic Fields There are two magic fields in each index entry. Their purpose is unknown. Magic 1 There is no information about the purpose of this field, but it seems to very roughly correlate with the size of the file. A rudimentary analysis of official files shows that Magic 1 is usually between 8 and 64 times smaller than the size of the file, with smaller files generally having closer values. Magic 2 This is no information about the purpose of this field, but in official MLPAs, it is always equal to the Start offset field. It may just be duplicated information, or it may have some yet unknown function. Manipulation Extracting files is a simple process of reading the header to locate the index, reading the index to locate the files, and then copying them out of the data segment. Likewise, rebuilding the archive is a simple process of building an index from a file list, then copying the files and the index together to create the archive. Creating the header is tricky, as it's length is based on it's value, and it's length will change it's value, but it's length can be locked to 9 digits fairly safely by prepending short values with 0. An example implementation can be found at MLPArch. Category:File Formats